# +----------------------------------------------------------------------
# | ChatWork智能聊天办公系统
# +----------------------------------------------------------------------
# | 软件声明: 本系统并非自由软件,未经授权任何形式的商业使用均属非法。
# | 版权保护: 任何企业和个人不允许对程序代码以任何形式任何目的复制/分发。
# | 授权要求: 如有商业使用需求,请务必先与版权所有者取得联系并获得正式授权。
# +----------------------------------------------------------------------
# | Author: ChatWork Team <2474369941@qq.com>
# +----------------------------------------------------------------------
import time
from tortoise.expressions import Q
from tortoise.functions import Count
from hypertext import PagingResult
from common.utils.times import TimeUtil
from common.enums.agent import AgentEnum
from common.models.agents import AgentKnowModel
from common.models.agents import AgentKnowArchiveModel
from common.postgres.public import PgKnowledgeModel
from apps.admin.schemas.agent.know import archive_schema as schema


class KnowArchiveService:

    @classmethod
    async def lists(cls, params: schema.KnowArchiveSearchIn) -> PagingResult[schema.KnowArchiveListVo]:
        """
        文档列表。

        Args:
            params (schema.KnowArchiveSearchIn): 文档查询参数。

        Returns:
            PagingResult[schema.KnowArchiveListVo]: 文档分页列表Vo。

        Author:
            zero
        """
        # 查询条件
        where = AgentKnowArchiveModel.build_search({
            "%like%": ["keyword@name"]
        }, params.__dict__)

        if params.know_id:
            where.append(Q(know_id=params.know_id))

        # 查询数据
        _model = AgentKnowArchiveModel.filter(*where).order_by("-update_time")
        _pager = await AgentKnowArchiveModel.paginate(
            model=_model,
            page_no=params.page_no,
            page_size=params.page_size
        )

        # 统计文档数据
        total_data = {}
        waits_data = {}
        yes_data = {}
        archive_ids = [item["id"] for item in _pager.lists if item["id"]]
        if archive_ids:
            # 全部的数据量
            total_query = await (PgKnowledgeModel
                                 .filter(is_delete=0)
                                 .filter(archive_id__in=archive_ids)
                                 .annotate(count=Count("archive_id"))
                                 .group_by("archive_id")
                                 .values_list("archive_id", "count"))

            # 待学习数据量
            waits_query = await (PgKnowledgeModel
                                 .filter(is_delete=0)
                                 .filter(archive_id__in=archive_ids)
                                 .filter(status=AgentEnum.EMB_WAIT)
                                 .annotate(count=Count("archive_id"))
                                 .group_by("archive_id")
                                 .values_list("archive_id", "count"))

            # 学习成功数据量
            yes_query = await (PgKnowledgeModel
                               .filter(is_delete=0)
                               .filter(archive_id__in=archive_ids)
                               .filter(status=AgentEnum.EMB_YES)
                               .annotate(count=Count("archive_id"))
                               .group_by("archive_id")
                               .values_list("archive_id", "count"))

            total_data = {k: v for k, v in total_query}
            waits_data = {k: v for k, v in waits_query}
            yes_data = {k: v for k, v in yes_query}

        # 知识库
        know_ids = [int(item["know_id"]) for item in _pager.lists if item["know_id"]]
        knows: dict = await AgentKnowModel.queryKnowDictsById(know_ids, field=["id", "name"])

        # 处理数据
        _lists = []
        for item in _pager.lists:
            know = knows.get(item["know_id"], {})
            _lists.append(schema.KnowArchiveListVo(
                id=item["id"],
                code=item["code"],
                name=item["name"],
                know=know.get("name") or "",
                train_mode=item["train_mode"],
                train_total=total_data.get(item["id"], 0),
                train_waits=waits_data.get(item["id"], 0),
                train_yes=yes_data.get(item["id"], 0),
                is_disable=item["is_disable"],
                create_time=item["create_time"],
                update_time=item["update_time"]
            ))

        _pager.lists = _lists
        return _pager

    @classmethod
    async def detail(cls, fid: int) -> schema.KnowArchiveDetailVo:
        """
        文档详情。

        Args:
            fid (int): 文档ID。

        Returns:
            schema.KnowArchiveDetailVo: 文档详情Vo。

        Author:
            zero
        """
        detail = await AgentKnowArchiveModel.filter(id=fid).get()
        return schema.KnowArchiveDetailVo(
            code=detail.code,
            name=detail.name,
            size=detail.size,
            train_mode=detail.train_mode,
            is_disable=detail.is_disable,
            create_time=TimeUtil.timestamp_to_date(detail.create_time),
            update_time=TimeUtil.timestamp_to_date(detail.update_time)
        )

    @classmethod
    async def delete(cls, fid: int):
        """
        文档删除。

        Args:
            fid (int): 文档ID。

        Author:
            zero
        """
        await AgentKnowArchiveModel.filter(id=fid).get()
        await AgentKnowArchiveModel.filter(id=fid).update(
            is_delete=1,
            delete_time=int(time.time())
        )
